/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.jspx.scriptmark.core.dispose;

import com.jspx.scriptmark.Phrase;
import com.jspx.scriptmark.ScriptRunner;
import com.jspx.scriptmark.ListIterator;
import com.jspx.scriptmark.core.block.BreakBlock;
import com.jspx.scriptmark.core.TagNode;
import com.jspx.scriptmark.core.EnvRunner;
import com.jspx.scriptmark.core.block.ContinueBlock;
import com.jspx.scriptmark.core.script.ScriptTypeConverter;
import com.jspx.scriptmark.core.iterator.RangeIterator;
import com.jspx.scriptmark.core.block.ListBlock;
import com.jspx.scriptmark.exception.ScriptException;
import com.jspx.scriptmark.exception.ScriptRunException;
import com.jspx.utils.StringUtil;
import java.io.Writer;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: chenYuan
 * Date: 2009-1-2
 * Time: 16:22:10
 */
public class ListPhrase implements Phrase {

    public ListPhrase() {

    }

    public int getRun(EnvRunner env, TagNode tagNode, Writer out) throws Exception {
        ScriptRunner scriptEngine = env.getScriptRunner();
        ListBlock listBlock = (ListBlock) tagNode;
        ///listBlock.getListName(); 可能就是一个表达式
        String listName = listBlock.getListName();
        if (!StringUtil.hasLength(listName)) {
            throw new ScriptException("error list tag ,列表表达式中的列表名称错误", listBlock.getSource(), tagNode.getLineNumber(), tagNode.getStarLength());

        }
        ListIterator listIterator;
        if (listName.contains("..")) {
            String sBegin = StringUtil.substringBefore(listName, "..");
            if (sBegin.startsWith("[")) sBegin = sBegin.substring(1);
            String send = StringUtil.substringAfter(listName, "..");
            if (send.endsWith("]")) send = send.substring(0, send.length() - 1);
            Object low;
            Object hig;

            if (ScriptTypeConverter.isStandardNumber(sBegin)) {
                low = StringUtil.toInt(sBegin);
            } else if (scriptEngine.containsVar(sBegin)) {
                low = scriptEngine.eval(sBegin,listBlock.getLineNumber());
            } else {
                low = sBegin;
            }
            if (ScriptTypeConverter.isStandardNumber(send)) {
                hig = StringUtil.toInt(send);
            } else if (scriptEngine.containsVar(send)) {
                hig = scriptEngine.eval(send,listBlock.getLineNumber());
            } else {
                hig = send;
            }
            if (!listBlock.getEquals() && low == hig) return 0;
            listIterator = new RangeIterator(low, hig);

        } else {
            try {
                listIterator = ScriptTypeConverter.getCollection(scriptEngine.eval(listName,listBlock.getLineNumber()));
            } catch (Exception e) {
                throw new ScriptRunException(tagNode,tagNode.getTagName());
            }
        }

        int bc = 0;
        String varName = listBlock.getVarName();
        if (listIterator != null)
            while (listIterator.hasNext()) {
                scriptEngine.put(varName + "_index", listIterator.getIndex());
                scriptEngine.put(varName + "_even", listIterator.getIndex() % 2 == 0);
                scriptEngine.put(varName, listIterator.next());
                scriptEngine.put(varName + "_has_next", listIterator.hasNext());
                List<TagNode> childNode = listBlock.getChildList();
                //如果在循环中碰到错误，保持已经处理的数据，并返回,如果抛出异常就不能保持处理结果了
                for (TagNode node : childNode) {
                    try
                    {
                        bc = env.runBlock(node, out);
                    } catch (Exception e) {
                        if (e instanceof ScriptRunException)
                        {
                            ScriptRunException ex = (ScriptRunException)e;
                            if (ex.getTagNode()!=null)
                            {
                                throw ex;
                            }
                        }
                       node.setErrorLine(node.getLineNumber());
                       throw new ScriptRunException(node,node.getTagName());
                    }
                    if (bc == ContinueBlock.value || bc == BreakBlock.value) break;       //相当于conintue
                }
                childNode.clear();
                if (bc == BreakBlock.value) break;
            }
        return 0;
    }
}